export class TableComponent {
  public page = 1;
  public itemsPerPage = 10;
  public maxSize = 5;
  public numPages = 1;
  public length = 0;
  public columns: Array<any>;
  public config: any;
  public ng2TableData: Array<any> = [];
  public rows: Array<any> = [];
  constructor(options: any) {
    if (options) {
      this.page = options.page && options.page > -1 ? options.page : this.page;
      this.itemsPerPage = options.itemsPerPage && options.itemsPerPage > -1 ? options.itemsPerPage : this.itemsPerPage;
      this.maxSize = options.maxSize && options.maxSize > -1 ? options.maxSize : this.maxSize;
      this.numPages = options.numPages && options.numPages > -1 ? options.numPages : this.numPages;
      this.length = options.length && options.length > -1 ? options.length : this.length;
      this.columns = options.columns ? options.columns : this.columns;
      this.config = options.config ? options.config : {};
      this.ng2TableData = options.ng2TableData ? options.ng2TableData : this.ng2TableData;
      this.rows = options.rows ? options.rows : this.rows;
    }
  }
  public changePage(page: any, data: Array<any> = this.ng2TableData): Array<any> {
    const start = (page.page - 1) * page.itemsPerPage;
    const end = page.itemsPerPage > -1 ? (start + page.itemsPerPage) : data.length;
    return data.slice(start, end);
  }

  public changeSort(data: any, config: any): any {
    if (!config.sorting) {
      return data;
    }

    const columns = this.config.sorting.columns || [];
    let columnName: string = void 0;
    let sort: string = void 0;

    for (let i = 0; i < columns.length; i++) {
      if (columns[i].sort !== '' && columns[i].sort !== false) {
        columnName = columns[i].name;
        sort = columns[i].sort;
      }
    }

    if (!columnName) {
      return data;
    }

    // simple sorting
    return data.sort((previous: any, current: any) => {
      if (previous[columnName] > current[columnName]) {
        return sort === 'desc' ? -1 : 1;
      } else if (previous[columnName] < current[columnName]) {
        return sort === 'asc' ? -1 : 1;
      }
      return 0;
    });
  }

  public changeFilter(data: any, config: any): any {

    let filteredData: Array<any> = data;
    this.columns.forEach((column: any) => {
      if (column.filtering) {
        filteredData = filteredData.filter((item: any) => {
          item[column.name] = item[column.name] == null ? '' : item[column.name];
          return item[column.name].match(column.filtering.filterString);
        });
      }
    });

    if (!config.filtering) {
      return filteredData;
    }

    if (config.filtering.columnName) {
      return filteredData.filter((item: any) => {
        item[config.filtering.columnName] = item[config.filtering.columnName] == null ? '' : item[config.filtering.columnName];
        item[config.filtering.columnName].match(this.config.filtering.filterString);
      });
    }

    const tempArray: Array<any> = [];
    filteredData.forEach((item: any) => {
      let flag = false;
      this.columns.forEach((column: any) => {
        item[column.name] = item[column.name] == null ? '' : item[column.name];
        if (item[column.name].toString().match(this.config.filtering.filterString)) {
          flag = true;
        }
      });
      if (flag) {
        tempArray.push(item);
      }
    });
    filteredData = tempArray;

    return filteredData;
  }

  public onChangeTable(config: any, page: any = { page: this.page, itemsPerPage: this.itemsPerPage }): any {
    config = config ? config : this.config;
    if (config.filtering) {
      (<any>Object).assign(this.config.filtering, config.filtering);
    }

    if (config.sorting) {
      (<any>Object).assign(this.config.sorting, config.sorting);
    }
    const filteredData = this.changeFilter(this.ng2TableData, this.config);
    filteredData.forEach((item: any) => {
      this.columns.forEach((column: any) => {
        item[column.name] = item[column.name] == null ? '' : item[column.name];
        if (column.formatter && typeof column.formatter === 'function') {
          item[column.name] = column.formatter(item[column.name]);
        }
      });
    });
    const sortedData = this.changeSort(filteredData, this.config);
    this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;
    this.length = sortedData.length;
  }
}
